package gen.tools.jenkins;

import gen.tools.JobDepStruc;
import gen.tools.Widgets;
import gen.tools.structures.B1I1;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TriggerRecovery extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public TriggerRecovery() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request,response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		final Widgets wid = new Widgets();
		request.setCharacterEncoding( wid.UIcodeSet );
		response.setCharacterEncoding( wid.UIcodeSet );
		response.setContentType("application/text");
		
		final int chkInId = Integer.parseInt(request.getParameter("chkInMainId"));	//繳交申請ID
		final int cmFileVer = Integer.parseInt(request.getParameter("cmFileVer"));	//欲使用的CM OL版次
		final String subsysId = request.getParameter("subsysId");
		final String applierId = request.getParameter("empId");
		
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		
		String res="OK";
		
		try {
			conn = wid.getConn();
			
			String sql = "SELECT modId FROM chkinmod WHERE chkInMainId=?";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, chkInId);
			rs = ps.executeQuery();
			
			ArrayList<JobDepStruc> jds = new ArrayList<JobDepStruc>();	//儲存這次繳交有影響到的模組
			
			while ( rs.next() ) {
				//產生屬於該模組的樹結構
				JobDepStruc jd = new JobDepStruc( rs.getString("modId"),false,subsysId );
				jd = wid.buildTree(jd);
				jd.setUp(null);
				jds.add(jd);
			}
			/**	
			 *	比對模組間是否存在依附的關係，如  A模組在建置的過程中會產生B，最後推導出C.ear
			 *	這時 A 和 B 的內容都被提交，則最後僅該部署一次 c.ear即可
			 *
			 *	故以下程式的邏輯便是檢查，若 B tree 包含在 A tree中，之間刪除 B tree，僅執行 A tree的動作即可
			 */
			
			//	b1 是否被包含
			//	i1 流水號
			final ArrayList<B1I1> jds4Chk = new ArrayList<B1I1>();	//與所有節點同樣大小的清單
			for(int i=0;i<jds.size();i++) {	//初始化 jds4Chk， 其中的B1皆先設為false，假設沒有要跑
				final B1I1 jd4Chk = new B1I1();
				jd4Chk.setI1(i);
				jd4Chk.setB1(false);	//false代表沒有被包含，B1代表  isContained
				System.out.println("建立了"+jds.get(i).getModId()+"的核對ArrayList");
				jds4Chk.add(jd4Chk);
			}
			for(int i=0;i<jds.size();i++) {
				for(int j=0;j<jds.size();j++) {
					if ( i!=j && !jds4Chk.get(j).isB1() ) {	//不用比對自己，而且若自己已證實被包含，也不用算了
						if( jds.get(i).isContain(jds.get(i), jds.get(j).getModId()) ){
							System.out.println(jds.get(i).getModId()+"包含了"+jds.get(j).getModId());
							jds4Chk.get(j).setB1(true);
						} else {
							System.out.println(jds.get(i).getModId()+"未包含"+jds.get(j).getModId());
						}
					}
				}
			}
			//利用上面比對的結果，移除掉會被重覆部署的chain
			for(int i=0;i<jds4Chk.size();i++) {
				if( jds4Chk.get(i).isB1() ){
					System.out.println(jds.get(i).getModId()+"被包含了，要移除");
					jds.remove(i);
				}
			}
			
			/**
			 * 開始處理 Build版封裝
			 * */
			
			for(int i=0;i<jds.size();i++) {
				/*
				 * 1. 將第一層的模組，其xml加上chkInId的參數
				 * 2. 驅動部署
				 * */
				final String jobName = (jds.get(i).isMR()?"MR":"OL")+"_"+jds.get(i).getSubsysId()+"_"+jds.get(i).getModId();
				final String upstreamJobName = jobName;
				final String rootJobName = jobName;
				wid.updateJenkinsJobPostBuildURL(jobName,chkInId,subsysId,applierId, upstreamJobName, 0, rootJobName,0);
				//wid.updateJobPostBuildURL( jobName, chkInId,null,0,null, 0, applierId);
				try {
					System.out.println("要觸發的Job是："+jobName+",欲使用的版次是："+cmFileVer);
					wid.updateJenkinsJobSVNver(jobName, cmFileVer);
					System.out.println("變更Jenkins上的SVN執行版次成功");
					wid.triggerJenkinsBuild( jobName );
				} catch (Exception e) {
					//驅動jenkins失敗
					int chkInStatusId = 6;
					wid.updateCHKINstatus(chkInId, chkInStatusId);
					wid.errLog(e);
					res= e.toString();
				}
			}
		} catch(Exception e) {
			wid.errLog(e);
			res = e.toString();
		} finally {
			try {
				if ( rs !=null ) {rs.close();}
				if ( ps !=null ) {ps.close();}
				if ( conn !=null ) {conn.close();}	
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		response.getWriter().write( res );
	}

}
